//
//  MoreThreadVC.m
//  ShandsMod
//
//  Created by zh_s on 3/2/22.
//  Copyright © 2022 zh_s. All rights reserved.


//  多线程相关

#import "MoreThreadVC.h"

@interface MoreThreadVC ()

@end

@implementation MoreThreadVC

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navTitle = @"多线程相关";
//    [self interview3];
    
    [self groupThread1];
}
#pragma mark ----- GCD死锁相关面试
- (void)interview {
    //问题1:以下在主线程执行,会造成死锁吗?
    
    //会造成死锁 因为是在sync是在当前线程的主队列立马执行 "2222" 但是当前线程主队列有个"3333"需要执行, 主队列都是串行队列,遵循先进先出原则,"333"还没有执行完就要执行"222" 就造成了死锁
    
    NSLog(@"111");
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
    
        NSLog(@"222");
        
    });
    //这个去掉也会造成死锁
    NSLog(@"3333");
}

- (void)interview1 {
    //问题2:以下在主线程执行,会造成死锁吗?
    
    //不会,异步队列不要求当前线程执行任务
    NSLog(@"111");
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_async(queue, ^{
        NSLog(@"222");
        
    });
    NSLog(@"3333");
}

- (void)interview2 {
    //问题3:以下在主线程执行,会造成死锁吗?
    
    //会,因为式串行队列,决定了异步任务的block要按顺序执行,block中遇到同步任务就又违背了串行队列特点,先进先出,导致两个任务冲突
    
    NSLog(@"111");
    //SERIAL 串行队列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"222");
        
        dispatch_sync(queue, ^{
            NSLog(@"333");
        });
        
        NSLog(@"444");
    });
    NSLog(@"555");
}

- (void)interview3 {
    //问题4:以下在主线程执行,会造成死锁吗?
    
    //不会,
    
    NSLog(@"111");
    //SERIAL 串行队列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
    //CONCURRENT 并行队列
    dispatch_queue_t queue1 = dispatch_queue_create("myQueue1", DISPATCH_QUEUE_CONCURRENT);//创建新的并发低劣
    //获取全局并发队列
    //dispatch_get_global_queue(0, 0);
    dispatch_sync(queue, ^{
        NSLog(@"222");
        
        dispatch_async(queue1, ^{
            NSLog(@"333");
        });
        
        NSLog(@"444");
    });
    NSLog(@"555");
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    
    dispatch_queue_t queue = dispatch_queue_create("myrun", DISPATCH_QUEUE_SERIAL);

    dispatch_async(queue, ^{
        JTDLog(@"1");
        /// afterDelay 是向runloop中添加定时器,子线程默认没有启动runloop
        [self performSelector:@selector(test) withObject:nil afterDelay:0.0];
        
        JTDLog("3");
        //启动runloop 没有销毁的
        [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    });
//
    
//    NSThread *thread = [[NSThread alloc] initWithBlock:^{
//        JTDLog("111");
//    }];
//    [thread start];
////    /子线程中没有开启runloop 执行结束后就退出了,在调用thread就会崩溃,没有线程保活?
//    [self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
}

- (void)test {
    JTDLog("2");
}

- (void)groupThread {
    //1、异步并发执行任务1、任务2
    //2、等任务1、任务2都执行完毕后，再回到主线程执行任务3
    
    ///创建队列组
    dispatch_group_t group = dispatch_group_create();
    ///创建一个并发队列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    ///把并发队列和队列组添加到异步任务中
    dispatch_group_async(group, queue, ^{
        
        for (int i = 0 ; i < 6; i ++) {
            NSLog(@"任务1=%d",i);
        }
    });

    dispatch_group_async(group, queue, ^{

        for (int j = 10 ; j < 16; j ++) {
            NSLog(@"任务2=%d",j);
        }
    });

    ///回到主线程执行任务三
    dispatch_group_notify(group, queue, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            for (int i = 20 ; i < 24; i ++) {
                NSLog(@"任务3=%d",i);
            }
        });
    });
}

- (void)groupThread1 {
    //1、异步并发执行任务1、任务2
    //2、等任务1、任务2都执行完毕后，再执行任务3、 任务4 且任务3、 任务4异步并发执行
    
    ///创建队列组
    dispatch_group_t group = dispatch_group_create();
    ///创建一个并发队列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    ///把并发队列和队列组添加到异步任务中
    dispatch_group_async(group, queue, ^{
        
        for (int i = 0 ; i < 6; i ++) {
            NSLog(@"任务1=%d",i);
        }
    });

    dispatch_group_async(group, queue, ^{

        for (int j = 10 ; j < 16; j ++) {
            NSLog(@"任务2=%d",j);
        }
    });
    
    
    dispatch_group_notify(group, queue, ^{
        ///把并发队列和队列组添加到异步任务中
        dispatch_group_async(group, queue, ^{
            for (int i = 0 ; i < 6; i ++) {
                NSLog(@"任务3=%d",i);
            }
        });
        dispatch_group_async(group, queue, ^{
            for (int j = 10 ; j < 16; j ++) {
                NSLog(@"任务4=%d",j);
            }
        });
        
    });
    
    
}

@end
